# encoding: utf-8
import os
import random
import pypinyin  # 需要安装pypinyin库
from colorama import Style,Fore,init

#----------8小时环游地球----------
BASE_FOLDER = "8小时环游地球文件"

init(autoreset=True) #颜色初始化

def edition():  # 定义版本函数
    """版本"""
    edition = '1.4'
    return Fore.GREEN + f'当前版本：{edition}'

class AroundTheWorldIn8Hours:  #标志本文档功能与版本号
    def __init__(self):
        """定义初始化"""
        if not os.path.exists(BASE_FOLDER):
            os.makedirs(BASE_FOLDER)

        self.city1_ = set()  # 初始化中文城市集合
        self.city2_ = set()  # 初始化英文城市集合
        self.city1_visit = set()  # 初始化中文游览记录
        self.city2_visit = set()  # 初始化英文游览记录
        self.search_history_cn1 = set()  # 初始化中文搜索记录1
        self.search_history_cn2 = set()  # 初始化中文搜索记录2
        self.search_history_en1 = set()  # 初始化英文搜索记录1
        self.search_history_en2 = set()  # 初始化英文搜索记录2

        self.load_cities_from_folder()  # 初始化“从文件夹加载城市数据”函数

    def load_cities_from_folder(self) -> None: #定义“从文件夹加载城市数据”函数，有效避免代码冗余
        """从文件夹加载数据"""
        if not os.path.exists(BASE_FOLDER):
            print(f"错误：文件夹 {BASE_FOLDER} 不存在，已创建新文件夹")
            os.makedirs(BASE_FOLDER)
            return

        for filename in os.listdir(BASE_FOLDER):
            file_path = os.path.join(BASE_FOLDER, filename)
            if os.path.isfile(file_path):
                if "；中文" in filename:  #严格注意分号书写规范！
                    city_name = filename.split("；")[0]
                    self.city1_.add(city_name)
                elif ";English" in filename:
                    city_name = filename.split(";")[0]
                    self.city2_.add(city_name)

#----------主程序----------
print(Style.BRIGHT+Fore.BLUE+'\n欢迎来到交互式城市游览程序!')
print('\n请先选择模式：'+Fore.RED+'（选择后无法更改）\n')
print('=====主页=====\n1.简体中文（查看模式）;\n2.English（Reading）\n3.上传Uploading\n4.开发者模式')

choice_lan = input('选择你的语言:')

if not os.path.exists(BASE_FOLDER):
    os.makedirs(BASE_FOLDER)

#----------语言选择与判断----------
def language_choose():
    """语言选择"""
    if choice_lan in ['1', 'Chinese', 'chinese', '简体中文', '中文']:
        return '1'
    elif choice_lan in ['2', 'English', 'eng', 'english']:
        return '2'
    elif choice_lan in ['3', '上传', 'upload']:
        return '3'
    else:
        return '0'

result = language_choose()
system = AroundTheWorldIn8Hours()

# ----------中文模式----------
if result == '1':
    print(Style.BRIGHT+Fore.BLUE+'\n你选择了中文')
    city1_visit = set()

    while True:
        print(Style.BRIGHT+Fore.BLUE+'\n=====中文菜单=====\n')
        print('<1>选择你想游览的城市\n<2>退出\n<3>随机\n<4>搜索')
        input_city = input("请输入操作名称：(如“1”或“<1>”均可识别)")

        if input_city in ['1', '<1>']:
            if system.city1_:
                print(Style.BRIGHT+Fore.BLUE+'=====阅读菜单=====')
                print('\n当前可查看的城市有：', "，".join(system.city1_))
            else:
                print(Style.BRIGHT+Fore.RED +"=====阅读菜单====="+"\n当前没有可查看的城市，请先上传城市信息")
                continue  # 没有城市数据时跳过

            city_other_names = {
                city: [
                    city,
                    ''.join(pypinyin.lazy_pinyin(city, style=pypinyin.Style.NORMAL)),
                    ''.join(pypinyin.lazy_pinyin(city, style=pypinyin.Style.NORMAL)).capitalize()
                ] #排除所有误输入情况，方便输入，此处支持：正常中文输入；“首字母大写”；“小写”；“全部大写”的情况
                for city in system.city1_
            }
                    #在文件夹中寻找遍历所有文件并创建集合

            def process_city_cn(input_city_fix_cn, city_other_names, city_visit_set):
                """城市游览中文函数"""
                if not input_city_fix_cn:  # 处理空输入
                    print(Fore.RED +'不得输入空内容！')
                    return False

                normalized_city = input_city_fix_cn.lower()
                for city_name, aliases in city_other_names.items():
                    if normalized_city in [a.lower() for a in aliases]:
                        file_path = os.path.join(BASE_FOLDER, f"{city_name}；中文.txt")
                        try:
                            print(Fore.GREEN+f'欢迎游览{city_name}')
                            with open(file_path, 'r', encoding='utf-8') as file:
                                for line in file:
                                    print(line.strip())
                        except FileNotFoundError:
                            print(Fore.RED+f"文件 {file_path} 不存在，请确保文件已正确上传")

                        city_visit_set.add(city_name)
                        return True
                return False

            while True:
                input_city_fix_cn = input('请输入您想游览的城市：（例如“南京”，拼音亦可轻按回车以退出）')
                if  input_city_fix_cn=='':
                    break

                if not process_city_cn(input_city_fix_cn, city_other_names, city1_visit):
                    print(Fore.RED+"未找到匹配的城市，请重新输入")

        elif input_city in ['2', '<2>', '退出']:
            not_visit_yet_1 = system.city1_.difference(city1_visit)
            print('感谢您的阅读')
            if len(city1_visit)> 0:
                print('你已经游览：', *city1_visit)
            else:
                pass
            print('你还未游览：', *not_visit_yet_1)
            break

        elif input_city in ['3', '<3>', '随机']:
            if not system.city1_:
                print(Fore.RED+"\n暂无城市数据，请先上传城市信息")
                continue

            while True:
                print(Style.BRIGHT+Fore.BLUE+'\n=====随机菜单=====')
                print('欢迎使用随机模式！您可以选择：\n1.随机城市名称\n2.随机城市内容\n3.退出\n')
                random_choice = input('请输入您的选择： （如“1”；“名称”）')
                if random_choice in ['1', '名称']:
                    random_file = random.choice(list(system.city1_))
                    print(Fore.GREEN+f'为您选择的城市名称为：{random_file}')
                elif random_choice in ['2', '内容']:
                    random_file = random.choice(list(system.city1_))
                    file_path = os.path.join(BASE_FOLDER, f"{random_file}；中文.txt")
                    print(f'现在您可游览：{random_file}')
                    try:
                        with open(file_path, 'r', encoding='utf-8') as file:
                            for line in file:
                                print(line.strip())
                    except FileNotFoundError:
                        print(f"文件 {file_path} 不存在，请确保文件已正确上传")
                elif random_choice in ['3', '退出']:
                    print("已退出随机模式，现在您可前往阅读模式查看：",*system.city1_)
                    break

        elif input_city in ['4', '<4>', '搜索']:

            if not system.city1_:
                print(Fore.RED+"暂无城市数据，请先上传城市信息")
                continue

            while True:
                print(Style.BRIGHT+Fore.BLUE+'\n=====搜索菜单=====')
                print('[1]搜索城市名称\n[2]搜索首字\n（轻按回车以退出）')
                search_choice = input('请输入搜索类型： （如“1”、“[1]”均可）')

                if not search_choice:
                    break

                search_history_cn = set()
                def search_name_cn():
                    """中文名称搜索"""
                    while True:
                        search_city = input('输入你想查询的城市名称：(按回车退出) ').strip()

                        if search_city == '':
                            break

                        if search_city in system.city1_:
                            search_history_cn.add(search_city)
                            print(Fore.GREEN+f'查询到{search_city}！')

                        else:
                            search_history_cn.add(search_city)
                            print(Fore.RED+f'查询不到{search_city}，请重新输入')

                def search_first_word_cn():
                    """中文查询首字"""
                    while True:
                        first_word = input('请输入城市首字：(轻按回车以退出)').strip()
                        results = [city for city in system.city1_ if city.startswith(first_word)]

                        if len(first_word) > 1:
                            return Fore.RED+'请勿输入超过一个字的内容！'

                        if results:
                            for city in results:
                                search_history_cn.add(city)
                            return Fore.GREEN+f'搜索结果：{", ".join(results)}'

                        if first_word == '':
                            return '已经退出。'

                        else:
                            search_history_cn.add(f"首字:{first_word}")
                            return Fore.RED+f'搜索结果：没有找到以{first_word}开头的城市！'

                if search_choice in ['1', '[1]']:
                    search_name_cn()
                    print('您的搜索记录：', end='')
                    print(*search_history_cn, sep=' ')
                    search_history_choice = input('您想清除搜索记录吗？(是/否)')

                    if search_history_choice == '是':
                        search_history_cn.clear()  # 清空搜索记录
                        print('搜索记录已清空。')

                    elif search_history_choice == '否':
                        pass

                elif search_choice in ['2', '[2]']:
                    print(*search_first_word_cn())
                    print('您的搜索记录：', end='')
                    print(search_history_cn, sep=' ')

                    search_history_choice = input('您想清除搜索记录吗？(是/否)')
                    if search_history_choice == '是':
                        search_history_cn.clear()
                        print(Fore.GREEN+'搜索记录已清空。')

                    elif search_history_choice == '否':
                        pass

                # 每次搜索完成后，询问是否继续搜索

                continue_search = input('是否继续搜索？(是/否)')

                if continue_search.lower() == '否':
                    break

                elif search_history_choice == '是':
                    pass

        else:
            print(Fore.RED+'暂无此城市。')
            print(Fore.RED+'您可以前往上传模式，上传该城市信息。')

#----------英文模式-----------
elif result == '2':
    print(Style.BRIGHT+Fore.BLUE+'\nYou have chosen English.')
    city2_visit = set()

    while True:
        print(Style.BRIGHT+Fore.BLUE+'\n=====Menu=====\n------------------\n<1>Choose a city you want to visit\n<2>Back\n<3>Random\n<4>Search')
        input_city = input('please input a city you want to visit:')

        if input_city in ['1', '<1>']:
            if system.city2_:
                print(*Style.BRIGHT+Fore.BLUE+'=====READING MENU=====\nYou can read:', ", ".join(system.city2_))
            else:
                print("=====READING MENU=====\nNo available cities, please upload first")
                continue

            city_other_names_eng = {city: [city, city.lower(), city.upper()] for city in system.city2_}
            #城市别名
            def process_city_eng(input_city, city_other_names_eng, city_visit_set):
                normalized_city = input_city.lower()
                for city_name, aliases in city_other_names_eng.items():
                    if normalized_city in aliases:
                        file_path = os.path.join(BASE_FOLDER, f"{city_name};English.txt")
                        try:
                            with open(file_path, 'r', encoding='utf-8') as file:
                                for line in file:
                                    print(line.strip())
                        except FileNotFoundError:
                            print(*f"File {file_path} not found. Make sure it's uploaded correctly!")

                        city_visit_set.add(city_name)
                        return True
                return False

            if not process_city_eng(input_city, city_other_names_eng, city2_visit):
                print("City not found, please try again")

        elif input_city in ['2', '<2>', 'Back']:
            print('Thanks for your visiting.')
            print('You have visited:', *city2_visit)
            not_visit_yet_2 = system.city2_.difference(city2_visit)
            print('You have not visited :', *not_visit_yet_2)
            print(f"Folder path: {os.path.abspath(BASE_FOLDER)}")
            break

        elif input_city in ['3', '<3>', 'Random']:
            if not system.city2_:
                print("No city data available, please upload first")
                continue

            while True:
                print('=====RANDOM=====')
                random_choice = input('Welcome to RANDOM! You can choose：\n[1].Random Name\n[2].Random Intro\n[3].Back\n')
                if random_choice in ['1', '[1]','Name']:
                    random_file = random.choice(list(system.city2_))
                    print(f'The random city is：{random_file}')
                elif random_choice in ['2', '[2]','Introduction']:
                    random_file = random.choice(list(system.city2_))
                    file_path = os.path.join(BASE_FOLDER, f"{random_file};English.txt")
                    try:
                        with open(file_path, 'r', encoding='utf-8') as file:
                            for line in file:
                                print(line.strip())
                    except FileNotFoundError:
                        print(f"File {file_path} not found, make sure it's uploaded!")
                elif random_choice in ['3', '[3]','Back']:
                    print(f"Folder path：{os.path.abspath(BASE_FOLDER)}")
                    break

        elif input_city in ['4', '<4>', 'Search']:
            if not system.city2_:
                print("No city data available, please upload first")
                continue

            print('=====SEARCH MENU=====\n')
            search_choice = input('[1]Search for Name\n[2]Search First Letter\n')

            search_history_en1 = set()
            def search_name_eng():
                search_city = input('Input the NAME you want to search： ').strip()

                if search_city in system.city2_:
                    search_history_en1.add(search_city)
                    return f'{search_city}  is found！'
                else:
                    search_history_en1.add(search_city)
                    return f'{search_city} is not found，please try again!！'

            search_history_en2 = set()
            def search_first_word_eng():
                while True:
                    first_word = input('Please input the FIRST LETTER of Name：("Enter" to exit)').strip()

                    if first_word.lower() == '':
                        return 'You have exited'

                    if len(first_word) > 1: #处理长度大于1的首字母
                        return 'Do not input more than one letter!！'

                    results = [city for city in system.city2_ if city.startswith(first_word)]
                    if results:
                        for city in results:
                            search_history_en2.add(city)
                        return f'Search results：{", ".join(results)}'
                    else:
                        search_history_en2.add(f"First letter:{first_word}")
                        return f'Search results：No city starts with {first_word}'

            if search_choice in ['1', '[1]']:
                print(search_name_eng())
                print('Your search history：', end='')
                print(*search_history_en1, sep=' ')
            elif search_choice in ['2', '[2]']:
                print(search_first_word_eng())
                print('Your search history：', end='')
                print(*search_history_en2, sep=' ')
            else:
                print('City not found. Maybe visit another city.')

        else:
            print('Please input correctly!')

# ----------上传功能----------
elif result == '3':
    print('\n欢迎使用城市信息上传功能！')

    while True:
        print('上传菜单：\n<1>添加中文城市信息\n<2>添加英文城市信息\n<3>返回主菜单')
        upload_choice = input('请选择操作：')

        if upload_choice == '1':
            city_name = input('请输入城市名称（中文）：')
            if not city_name:
                print('城市名称不能为空！')
                continue

            city_eng = input('请输入城市英文名称：')
            if not city_eng:
                print('英文名称不能为空！')
                continue

            print(f'请输入关于{city_name}的介绍（输入"END"结束，至少一行）：')
            city_content = []
            while True:
                line = input()
                if line in ['END', 'end']:
                    break
                city_content.append(line)

            if not city_content:
                print('城市介绍不能为空！')
                continue

            file_name = f"{city_name}；中文.txt" #注意中英文分号的区别，否则无法正确读取！
            file_path = os.path.join(BASE_FOLDER, file_name)
            try:
                with open(file_path, 'w', encoding='utf-8') as file:
                    file.write('\n'.join(city_content))
                print(f'成功上传{city_name}的中文信息！')
                system.city1_.add(city_name)
                print(f'现在中文可游览城市：{system.city1_}')
            except Exception as e:
                print(f'上传失败：{e}')

        elif upload_choice == '2':
            city_name = input('Please input the English name of the city：')
            if not city_name:
                print('The name can not be empty！')
                continue

            city_chi = input('Please input the Chinese name of the city：')
            if not city_chi:
                print('The name can not be empty！')
                continue

            print(f'Please input the introduction of{city_name}（Input"END"to finish，At least ONE line）：')
            city_content = []
            while True:
                line = input()
                if line == 'END':
                    break
                city_content.append(line)

            if not city_content:
                print('The introduction cannot be empty!！')
                continue

            file_name = f"{city_name};English.txt"
            file_path = os.path.join(BASE_FOLDER, file_name)
            try:
                with open(file_path, 'w', encoding='utf-8') as file:
                    file.write('\n'.join(city_content))
                print(f'Succeeding to uploading the introduction of {city_name}！')
                system.city2_.add(city_name)
                print('Now you can visit：',*system.city2_)
            except Exception as e:
                print(f'Fail to upload：{e}')

        elif upload_choice == '3':
            break

        else:
            print('Error choice！Please input it again!')

    print(f"You can find the dir in：{os.path.abspath(BASE_FOLDER)}")

#----------开发者模式----------
elif choice_lan in ['4','开发者模式']:
    print('欢迎来到开发者模式！')
    #当前模式暂时仅支持简体中文

    def developer_helper() -> None:
        while True:
            print( Fore.BLUE+'\n=====开发者模式主页=====')
            print('1.问题反馈\n2.常见需求\n3.当前版本')
            developer_choice = input('请输入您的选择：（轻按回车以退出）')

            if developer_choice =='1':
                print('如在使用过程中，发现本程序有：语法、内容、格式或阅读等方面改进建议;')
                print('请发件至zhixingfang@qq.com 寻求帮助;')
                print('或在语雀上寻求帮助。')

            elif developer_choice == '2':
                print('您的需求可能如下：\n')
                print('1.交互性仍需增强。')
                print('2.程序存在漏洞。')
                print('3.语言过少。')

                developer_choice_2 = input('输入您的需求： ')
                if not developer_choice_2:
                    print('禁止输入空内容')

                else:
                    if developer_choice_2=='1':
                        print('您仅需在如print(),input(),return中修改即可；')
                    elif developer_choice_2=='2':
                        print('您可自行修改或进行反馈，具体可参考注释及本程序附带文档；')
                    elif developer_choice_2=='3':
                        print('您可仿照中、英文格式，仅修改交互提示即可，无需修改逻辑；')
                    else:
                        print('请发件至zhixingfang@qq.com 寻求帮助;\n或在语雀上寻求帮助')
            elif developer_choice =='3':
                print(edition())

            elif developer_choice == '':
                break
    developer_helper()
# 其他语言判断
elif result == '0':
    print('暂无该语言\n您可仿照前面的格式，自行添加语言（如：日文；俄文等）')